﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Collections;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.IO;
using System.Xml;


namespace FUSE
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class MapGenerator : GameComponent
    {
        public Thread thread;
        private PerformanceCounter cpuPerformance;
        public List<Map> mapList;
        public List<Map> tutorialMapList;
        public static int numthreads = 0;
        public int numberOfMaps = 2;
        private int currentLevelMapCounter = 0;
        private int numberOfGeneratedMaps = 0;
        private Boolean doTutorial;
        private int currentTutorialCounter = 0;

        public double maximumArea;
        
        public const int DEFAULT_NUMBER_COMPONENTS = 2;
        public const String DEFAULT_BACKGROUND = "mapBackground01";
        public const String DEFAULT_TEST_BACKGROUND = "TestBackground";
        public const String DEFAULT_START_PLANET = "startPlanet";
        public const String DEFAULT_END_PLANET = "endPlanet";
        public const String DEFAULT_PLANET = "newPlanetSmall";
        public const String DEFAULT_SUN = "star";
        public const String DEFAULT_WORMHOLE = "wormhole";
        public const String DEFAULT_BLACKHOLE = "bHoleSpriteSheet";

        //map values to set
        public int numberPlanets = 0;
        public int numberSuns = 0;
        public int numberWormholes = 0;
        public int numberBlackholes = 0;
        private int xSize = 0;
        private int ySize = 0;

        private Difficulty currDifficulty;

        public enum Difficulty
        {
            Tutorial = 0,
            Noob,
            Easy,
            Medium,
            Hard,
            Insane,
            AreYouSerious
        }


        int wormholeAreaOfEffect = 10;

        private static Random randomGenerator;
        private Texture2D mapBackground;
        //private Hashtable galaxyComponents;
        private Texture2D startPlanetTexture;
        private Texture2D endPlanetTexture;
        private Texture2D componentTexture;
        private Texture2D sunTexture;
        private Texture2D wormholeTexture;
        private Texture2D blackholeTexture;

        //private StartPlanet startPoint;
        //private EndPlanet endPoint;



        public MapGenerator(Game game)
            : base(game)
        {
            //this.startPoint = new StartPlanet();
            //this.endPoint = new EndPlanet();

            randomGenerator = new Random();

            this.currDifficulty = Difficulty.Tutorial;

            //this.galaxyComponents = new Hashtable();
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            this.doTutorial = true;

            base.Initialize();

            mapList = new List<Map>();
            tutorialMapList = new List<Map>();

            cpuPerformance = new PerformanceCounter();
            cpuPerformance.CategoryName = "Processor";
            cpuPerformance.CounterName = "% Processor Time";
            cpuPerformance.InstanceName = "_Total";




            ContentManager cm = Game.Content;

            this.startPlanetTexture = cm.Load<Texture2D>(DEFAULT_START_PLANET);
            this.endPlanetTexture = cm.Load<Texture2D>(DEFAULT_END_PLANET);
            this.componentTexture = cm.Load<Texture2D>(DEFAULT_PLANET);
            this.sunTexture = cm.Load<Texture2D>(DEFAULT_SUN);
            this.wormholeTexture = cm.Load<Texture2D>(DEFAULT_WORMHOLE);
            this.blackholeTexture = cm.Load<Texture2D>(DEFAULT_BLACKHOLE);
            this.mapBackground = cm.Load<Texture2D>(DEFAULT_BACKGROUND);

            //this.startPoint.Initialize();
            //this.startPoint.LoadContent(startPlanetTexture);
            //this.startPoint.SetCenterPosition(mapBackground.Width / 2, mapBackground.Height);

            //this.endPoint.Initialize();
            //this.endPoint.LoadContent(endPlanetTexture);
            //this.endPoint.SetCenterPosition(mapBackground.Width / 2, 0);
            loadTutorialMaps();
            //regenerateMaps();

        }

        private float getCpuUsage()
        {
            //
            //
            //
            // Jason... you are not allowed the CPU usage...
            //          you must first love before you can be loved...
            //
            //
            //
            return cpuPerformance.NextValue();
        }

        public override void Update(GameTime gameTime)
        {
            //regenerateMaps();
            float test = getCpuUsage();
            if (thread != null)
            {
                if (thread.IsAlive)
                {
                    if (test > 80.0f)
                    {
                        //thread.Suspend();
                    }

                    if (test <= 80.0f && thread.ThreadState == System.Threading.ThreadState.Suspended)
                    {
                        thread.Resume();
                    }

                }
            }
            base.Update(gameTime);
        }
       

        public void regenerateMaps()
        {
            //Creating child thread
            thread = new Thread(new ThreadStart(ThreadedFunctions));
            thread.Name = "MapGenerator";
            thread.IsBackground = true;
            thread.Start();

            //while child thread is not alive spinlock
            while (!thread.IsAlive)
            {
            }
        }

        public void ThreadedFunctions()
        {
            while (true)
            {
                //mapList.Count <= numberOfMaps
                if (mapList.Count() < numberOfMaps)
                {
                    numthreads++;
                    Map temp = GenerateMap();
                    PhysicsEngine.createGravityGrid2(temp);

                    //if(temp.valid = true)
                    MapValidator mv = new MapValidator(temp);
                    //validate is broken right now
                    Boolean isMapValid = mv.Validate();

                    //only add if validate returns true
                    if (isMapValid)
                    {
                        mapList.Add(temp);
                        numberOfGeneratedMaps++;
                    }

                    Console.WriteLine(isMapValid);
                }
                else
                {
                    Thread.Sleep(100);
                }
            }
        }
        

        public Map GenerateMap() // Will return a Map object
        {
            //Map demoMap = new Map(mapBackground.Width, mapBackground.Height);

            Difficulty tempDifficulty = this.difficultySettings();

            Map demoMap = new Map(mapBackground, this.xSize, this.ySize);

            demoMap.visualization = false;
            demoMap.currMapType = Map.MapType.Survival;
            demoMap.mapDifficulty = tempDifficulty;

            Hashtable galaxyComponents = new Hashtable();

            demoMap.BackgroundTexture = this.mapBackground;
                
            GenericForce[,] forces = new GenericForce[this.xSize, this.ySize];

            Rectangle mapBounds = new Rectangle(0, 0, this.xSize, this.ySize);


            StartPlanet startPoint = new StartPlanet();
            startPoint.Initialize();
            startPoint.LoadContent(startPlanetTexture);
            startPoint.SetCenterPosition((this.xSize / 2), (this.ySize - 1));

            EndPlanet endPoint = new EndPlanet();
            endPoint.Initialize();
            endPoint.LoadContent(endPlanetTexture);
            endPoint.SetCenterPosition((this.xSize / 2), 0);

            maximumArea = this.xSize * this.ySize;
            double startComponentArea = ((2d * Math.PI * startPoint.ComponentBounds.radius) / 2d);
            double endComponentArea = ((2d * Math.PI * endPoint.ComponentBounds.radius) / 2d);

            maximumArea -= (startComponentArea + endComponentArea);


            galaxyComponents.Add("StartPlanet", startPoint);
            galaxyComponents.Add("EndPlanet", endPoint);
            for (int index = 0; index < numberSuns; index++)
            {
                Sun sun = new Sun(randomGenerator.Next(10), 10);
                sun.LoadContent(sunTexture);
                double sunArea = (2d * Math.PI * sun.CrashCircle.radius);
                if ((maximumArea - sunArea) > 0)
                {
                    Vector2 sunPosition = generatePosition(sun, galaxyComponents, mapBounds);
                    sun.SetCenterPosition(sunPosition.X, sunPosition.Y);

                    galaxyComponents.Add("x" + sunPosition.X + "y" + sunPosition.Y, sun);
                    maximumArea -= sunArea;
                }
            }
            for (int index = 0; index < numberBlackholes; index++)
            {
                Blackhole blackhole = new Blackhole(randomGenerator.Next(10));
                blackhole.LoadContent(blackholeTexture);
                double blackholeArea = (2d * Math.PI * blackhole.CrashCircle.radius);
                if ((maximumArea - blackholeArea) > 0)
                {
                    Vector2 blackholePosition = generatePosition(blackhole, galaxyComponents, mapBounds);
                    blackhole.SetCenterPosition(blackholePosition.X, blackholePosition.Y);

                    galaxyComponents.Add("x" + blackholePosition.X + "y" + blackholePosition.Y, blackhole);
                    maximumArea -= blackholeArea;
                }
            }
            for (int index = 0; index < numberPlanets; index++)
            {
                Planet planet = new Planet(randomGenerator.Next(10), 10);
                planet.LoadContent(componentTexture);
                double planetArea = (2d * Math.PI * planet.OrbitCircle.radius);
                if ((maximumArea - planetArea) > 0)
                {
                    Vector2 planetPosition = generatePosition(planet, galaxyComponents, mapBounds);
                    planet.SetCenterPosition(planetPosition.X, planetPosition.Y);

                    galaxyComponents.Add("x" + planetPosition.X + "y" + planetPosition.Y, planet);
                    maximumArea -= planetArea;
                }
            }

            for (int index = 0; index < numberWormholes; index++)
            {
                //Set the radius of the circular space around the worm holes
                Wormhole wormholeAlpha = new Wormhole((wormholeTexture.Width / 2));
                Wormhole wormholeBeta = new Wormhole((wormholeTexture.Width / 2));

                wormholeAlpha.LoadContent(wormholeTexture);
                wormholeBeta.LoadContent(wormholeTexture);


                double wormholeArea = (2d * Math.PI * wormholeAlpha.AreaOfEffect.radius);
                if ((maximumArea - (2d * wormholeArea)) > 0)
                {
                    //Associate sister wormholes, also position of circle will be set
                    Vector2 wormholeAlphaPosition = generatePosition(wormholeAlpha, galaxyComponents, mapBounds);

                    //Center wormhole positions
                    wormholeAlpha.SetCenterPosition(wormholeAlphaPosition.X, wormholeAlphaPosition.Y);
                    galaxyComponents.Add("x" + wormholeAlphaPosition.X + "y" + wormholeAlphaPosition.Y, wormholeAlpha);

                    Vector2 wormholeBetaPosition = generatePosition(wormholeBeta, galaxyComponents, mapBounds);
                    wormholeBeta.SetCenterPosition(wormholeBetaPosition.X, wormholeBetaPosition.Y);
                    galaxyComponents.Add("x" + wormholeBetaPosition.X + "y" + wormholeBetaPosition.Y, wormholeBeta);

                    wormholeAlpha.sisterWormholePosition = wormholeBetaPosition;
                    wormholeBeta.sisterWormholePosition = wormholeAlphaPosition;
                    maximumArea -= (2d * wormholeArea);
                }
            }

            demoMap.galaxyComponentsTable = galaxyComponents;
            demoMap.galaxyForces = forces;

            return demoMap;
        }

        private Vector2 generatePosition(GalaxyComponent galaxyComponent, Hashtable gc, Rectangle mapBounds)
        {
            Circle targetCircle = new Circle();
            if ((galaxyComponent is Sun) || (galaxyComponent is Blackhole))
                targetCircle = ((MassedComponent)galaxyComponent).CrashCircle;
            else if (galaxyComponent is Wormhole)
                targetCircle = ((Wormhole)galaxyComponent).AreaOfEffect;
            else //You're a PLANET!!!
            {
                targetCircle.centerPOS = ((Planet)galaxyComponent).OrbitCircle.centerPOS;
                targetCircle.radius = ((Planet)galaxyComponent).OrbitCircle.radius + 25;
            }


            int randomXCoord = randomGenerator.Next((int)targetCircle.radius, (int)(mapBounds.Width -
                targetCircle.radius));
            int randomYCoord = randomGenerator.Next((int)targetCircle.radius, (int)(mapBounds.Height -
                targetCircle.radius));

            targetCircle.SetPosition(new Vector2(randomXCoord, randomYCoord));

            Boolean isTooClose = false;
            double distance = 0;

            while (!isTooClose)
            {

                foreach (DictionaryEntry item in gc)
                {
                    GalaxyComponent value = (GalaxyComponent)item.Value;

                    distance = value.ComponentBounds.DistanceFromCenter(targetCircle);
                    if (value is MassedComponent)
                    {
                        if (value is Planet)
                        {
                            if (distance <= (((Planet)value).OrbitCircle.radius + targetCircle.radius))
                            {
                                isTooClose = true;
                                break;
                            }
                        }
                        else if (distance <= (((MassedComponent)value).CrashCircle.radius + targetCircle.radius))
                        {
                            isTooClose = true;
                            break;
                        }
                    }
                    else
                    {
                        if (((value is EndPlanet) && (galaxyComponent is MassedComponent)) || ((value is StartPlanet) && (galaxyComponent is MassedComponent)))
                        {
                            if (distance <= (((GalaxyComponent)value).ComponentBounds.radius + ((MassedComponent)galaxyComponent).SlingCircle.radius))
                            {
                                isTooClose = true;
                                break;
                            }
                        }
                        else
                        {
                            //distance <= ((((GalaxyComponent)value).ComponentBounds.radius * 2) + circle.radius)
                            if (value is Wormhole)
                            {
                                if (distance <= ((((Wormhole)value).AreaOfEffect.radius * 1.25) + targetCircle.radius))
                                {
                                    isTooClose = true;
                                    break;
                                }
                            }
                            else if (distance <= ((((GalaxyComponent)value).ComponentBounds.radius * 1.25d) + targetCircle.radius))
                            {
                                isTooClose = true;
                                break;
                            }
                        }
                    }
                }

                if (isTooClose == true)
                {
                    randomXCoord = randomGenerator.Next((int)targetCircle.radius, (int)(mapBounds.Width -
                        targetCircle.radius));
                    randomYCoord = randomGenerator.Next((int)targetCircle.radius, (int)(mapBounds.Height -
                        targetCircle.radius));

                    targetCircle.SetPosition(new Vector2(randomXCoord, randomYCoord));

                    isTooClose = false;
                }
                else
                {
                    break;
                }
            }

            return new Vector2(randomXCoord, randomYCoord);
        }

        

        private Difficulty difficultySettings()
        {
            if (this.numberOfGeneratedMaps >= (Math.Pow((int)this.currDifficulty, 2)) + 4)
            {
                if (this.currDifficulty < Difficulty.AreYouSerious)
                {
                    this.currDifficulty++;
                }
                //this.currentLevelMapCounter = 0;
            }

            Difficulty tempDifficulty = Difficulty.Tutorial;
            if (this.currDifficulty == Difficulty.Tutorial)
            {
                tempDifficulty = Difficulty.Noob;
            }
            else
            {
                tempDifficulty = this.currDifficulty;
            }


            if (tempDifficulty == Difficulty.Noob)
            {
                this.xSize = 800;
                this.ySize = 1200;
                this.numberPlanets = 1;
                this.numberSuns = 1;
                this.numberWormholes = 1;
                this.numberBlackholes = 0;
            }
            else if (tempDifficulty == Difficulty.Easy)
            {
                this.xSize = 800;
                this.ySize = 1600;
                this.numberPlanets = 6;
                this.numberSuns = 2;
                this.numberWormholes = 2;
                this.numberBlackholes = 1;
            }
            else if (tempDifficulty == Difficulty.Medium)
            {
                this.xSize = 800;
                this.ySize = 1600;
                this.numberPlanets = 4;
                this.numberSuns = 2;
                this.numberWormholes = 1;
                this.numberBlackholes = 2;
            }
            else if (tempDifficulty == Difficulty.Hard)
            {
                this.xSize = 800;
                this.ySize = 1900;
                this.numberPlanets = 2;
                this.numberSuns = 4;
                this.numberWormholes = 1;
                this.numberBlackholes = 3;
            }
            else if (tempDifficulty == Difficulty.Insane)
            {
                this.xSize = 800;
                this.ySize = 2048;
                this.numberPlanets = 1;
                this.numberSuns = 5;
                this.numberWormholes = 0;
                this.numberBlackholes = 6;
            }
            else if (tempDifficulty == Difficulty.AreYouSerious)
            {
                this.xSize = 800;
                this.ySize = 1800;
                this.numberPlanets = 0;
                this.numberSuns = 0;
                this.numberWormholes = 30;
                this.numberBlackholes = 2;
            }

            return tempDifficulty;
        }

        public void loadTutorialMaps()
        {
            XmlTextReader reader = new XmlTextReader("../../../TutorialLevels.xml");
            Map tempMap = new Map();
            String mapType = "";
            String mapDifficulty = "";
            int width = 0;
            int height = 0;
            GalaxyComponent tempGalaxyComponent;
            String currComponentType = "";
            int componentXCoord = -1;
            int componentYCoord = -1;
            int sisterXCoord = -1;
            int sisterYCoord = -1;
            String entry = "";
            
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        if (reader.Name.Equals("map", StringComparison.CurrentCultureIgnoreCase))
                        {
                            tempMap = new Map();
                            mapType = "";
                            mapDifficulty = "";
                            width = 0;
                            height = 0;
                        }
                        else if (reader.Name.Equals("component", StringComparison.CurrentCultureIgnoreCase))
                        {
                            currComponentType = "";
                            componentXCoord = -1;
                            componentYCoord = -1;
                            sisterXCoord = -1;
                            sisterYCoord = -1;
                            entry = "";
                        }
                        break;
                    case XmlNodeType.Text:
                        entry = reader.Value;
                        break;
                    case XmlNodeType.EndElement:
                        if (reader.Name.Equals("map", StringComparison.CurrentCultureIgnoreCase))
                        {
                            PhysicsEngine.createGravityGrid2(tempMap);
                            this.tutorialMapList.Add(tempMap);
                        }
                        else if (reader.Name.Equals("maptype", StringComparison.CurrentCultureIgnoreCase))
                        {
                            mapType = entry;
                        }
                        else if (reader.Name.Equals("mapdifficulty", StringComparison.CurrentCultureIgnoreCase))
                        {
                            mapDifficulty = entry;
                        }
                        else if (reader.Name.Equals("component", StringComparison.CurrentCultureIgnoreCase))
                        {
                            if (currComponentType.Equals("Planet", StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempGalaxyComponent = new Planet(randomGenerator.Next(10), 10);
                                ((Planet)tempGalaxyComponent).LoadContent(componentTexture);
                                ((Planet)tempGalaxyComponent).SetCenterPosition(componentXCoord, componentYCoord);
                                tempMap.galaxyComponentsTable.Add("x" + componentXCoord + "y" + componentYCoord,
                                    tempGalaxyComponent);
                            }
                            else if (currComponentType.Equals("Sun", StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempGalaxyComponent = new Sun(randomGenerator.Next(10), 10);
                                ((Sun)tempGalaxyComponent).LoadContent(sunTexture);
                                ((Sun)tempGalaxyComponent).SetCenterPosition(componentXCoord, componentYCoord);
                                tempMap.galaxyComponentsTable.Add("x" + componentXCoord + "y" + componentYCoord,
                                    tempGalaxyComponent);
                            }
                            else if (currComponentType.Equals("EndPlanet", StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempGalaxyComponent = new EndPlanet();
                                ((EndPlanet)tempGalaxyComponent).Initialize();
                                ((EndPlanet)tempGalaxyComponent).LoadContent(endPlanetTexture);
                                ((EndPlanet)tempGalaxyComponent).SetCenterPosition(componentXCoord, componentYCoord);
                                tempMap.galaxyComponentsTable.Add("EndPlanet", tempGalaxyComponent);
                            }
                            else if (currComponentType.Equals("StartPlanet", StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempGalaxyComponent = new StartPlanet();
                                ((StartPlanet)tempGalaxyComponent).Initialize();
                                ((StartPlanet)tempGalaxyComponent).LoadContent(startPlanetTexture);
                                ((StartPlanet)tempGalaxyComponent).SetCenterPosition(componentXCoord, componentYCoord);
                                tempMap.galaxyComponentsTable.Add("StartPlanet", tempGalaxyComponent);
                            }
                            else if (currComponentType.Equals("BlackHole", StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempGalaxyComponent = new Blackhole(randomGenerator.Next(10));
                                ((Blackhole)tempGalaxyComponent).LoadContent(blackholeTexture);
                                ((Blackhole)tempGalaxyComponent).SetCenterPosition(componentXCoord, componentYCoord);
                                tempMap.galaxyComponentsTable.Add("x" + componentXCoord + "y" + componentYCoord,
                                    tempGalaxyComponent);
                            }
                            else if (currComponentType.Equals("Wormhole", StringComparison.CurrentCultureIgnoreCase))
                            {
                                if (sisterXCoord != -1 && sisterYCoord != -1)
                                {
                                    tempGalaxyComponent = new Wormhole(this.wormholeAreaOfEffect);
                                    ((Wormhole)tempGalaxyComponent).LoadContent(wormholeTexture);
                                    ((Wormhole)tempGalaxyComponent).SetCenterPosition(componentXCoord, componentYCoord);
                                    ((Wormhole)tempGalaxyComponent).sisterWormholePosition = new Vector2(sisterXCoord, sisterYCoord);
                                    tempMap.galaxyComponentsTable.Add("x" + componentXCoord + "y" + componentYCoord,
                                        tempGalaxyComponent);

                                    tempGalaxyComponent = new Wormhole(this.wormholeAreaOfEffect);
                                    ((Wormhole)tempGalaxyComponent).LoadContent(wormholeTexture);
                                    ((Wormhole)tempGalaxyComponent).SetCenterPosition(sisterXCoord, sisterYCoord);
                                    ((Wormhole)tempGalaxyComponent).sisterWormholePosition = new Vector2(componentXCoord, componentYCoord);
                                    tempMap.galaxyComponentsTable.Add("x" + sisterXCoord + "y" + sisterYCoord,
                                        tempGalaxyComponent);
                                }
                            }

                        }
                        else if (reader.Name.Equals("xSize", StringComparison.CurrentCultureIgnoreCase))
                        {
                            width = Int32.Parse(entry);
                            entry = "";
                        }
                        else if (reader.Name.Equals("ySize", StringComparison.CurrentCultureIgnoreCase))
                        {
                            height = Int32.Parse(entry);
                            entry = "";
                            tempMap = new Map(this.mapBackground, width, height);
                            if (mapType.Equals(Map.MapType.Tutorial.ToString(), StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempMap.currMapType = Map.MapType.Tutorial;
                            }
                            else if (mapType.Equals(Map.MapType.Survival.ToString(), StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempMap.currMapType = Map.MapType.Survival;
                            }

                            if (mapDifficulty.Equals(MapGenerator.Difficulty.Tutorial.ToString(), StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempMap.mapDifficulty = MapGenerator.Difficulty.Tutorial;
                            }
                            else if (mapDifficulty.Equals(MapGenerator.Difficulty.Noob.ToString(), StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempMap.mapDifficulty = MapGenerator.Difficulty.Noob;
                            }
                            else if (mapDifficulty.Equals(MapGenerator.Difficulty.Easy.ToString(), StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempMap.mapDifficulty = MapGenerator.Difficulty.Easy;
                            }
                            else if (mapDifficulty.Equals(MapGenerator.Difficulty.Medium.ToString(), StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempMap.mapDifficulty = MapGenerator.Difficulty.Medium;
                            }
                            else if (mapDifficulty.Equals(MapGenerator.Difficulty.Hard.ToString(), StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempMap.mapDifficulty = MapGenerator.Difficulty.Hard;
                            }
                            else if (mapDifficulty.Equals(MapGenerator.Difficulty.Insane.ToString(), StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempMap.mapDifficulty = MapGenerator.Difficulty.Insane;
                            }
                            else if (mapDifficulty.Equals(MapGenerator.Difficulty.AreYouSerious.ToString(), StringComparison.CurrentCultureIgnoreCase))
                            {
                                tempMap.mapDifficulty = MapGenerator.Difficulty.AreYouSerious;
                            }
                        }
                        else if (reader.Name.Equals("type", StringComparison.CurrentCultureIgnoreCase))
                        {
                            currComponentType = entry;
                            entry = "";
                        }
                        else if (reader.Name.Equals("xcoord", StringComparison.CurrentCultureIgnoreCase))
                        {
                            componentXCoord = Int32.Parse(entry);
                            entry = "";
                        }
                        else if (reader.Name.Equals("ycoord", StringComparison.CurrentCultureIgnoreCase))
                        {
                            componentYCoord = Int32.Parse(entry);
                            entry = "";
                        }
                        else if (reader.Name.Equals("sisterycoord", StringComparison.CurrentCultureIgnoreCase))
                        {
                            sisterXCoord = Int32.Parse(entry);
                            entry = "";
                        }
                        else if (reader.Name.Equals("sisterycoord", StringComparison.CurrentCultureIgnoreCase))
                        {
                            sisterYCoord = Int32.Parse(entry);
                            entry = "";
                        }
                        else if (reader.Name.Equals("maplist", StringComparison.CurrentCultureIgnoreCase))
                        {
                            tempMap = new Map();
                            width = 0;
                            height = 0;
                            tempGalaxyComponent = new Planet();
                            currComponentType = "";
                            componentXCoord = -1;
                            componentYCoord = -1;
                            sisterXCoord = -1;
                            sisterYCoord = -1;
                            entry = "";
                        }
                        break;
                }
            }

            regenerateMaps();
        }

        public Map getMap()
        {
            Map temp = null;
            /*if (this.mapList.Count != 0)
            {*/
                /*
                temp = this.mapList.First<Map>();
                //temp.galaxyComponentsTable = (this.mapList.First<Map>()).galaxyComponentsTable;
                //temp.galaxyForces = (this.mapList.First<Map>()).galaxyForces;
                if (temp.currMapType == Map.MapType.Survival)
                {
                    this.currentLevelMapCounter++;
                }
                else
                {
                    this.currentTutorialCounter++;
                }
                
                this.mapList.RemoveAt(0);*/
            if (this.doTutorial)
            {
                temp = tutorialMapList[currentTutorialCounter];
                currentTutorialCounter++;

                if (currentTutorialCounter == 5)
                {
                    this.doTutorial = false;
                    this.currDifficulty = Difficulty.Noob;
                }
            }
            else
            {
                temp = this.mapList.First<Map>();
                this.currentLevelMapCounter++;
                this.mapList.RemoveAt(0);
            }

            /*}*/
            return temp;
        }
        public int getMapListCount()
        {
            return mapList.Count();
        }


        /*public void setDifficulty(Difficulty difficulty)
        {
            this.currDifficulty = difficulty;
            this.Reset();
        }*/

        private void Reset()
        {
            if (this.doTutorial)
            {
                if (thread != null)
                {
                    if (thread.IsAlive)
                    {
                        thread.Abort();
                    }
                }

                checkMapsForCorrectDifficulty();
                this.mapList.Clear();
                this.currentTutorialCounter = 0;
                this.currentLevelMapCounter = 0;
                this.regenerateMaps();
            }
            else
            {
                if (thread != null)
                {
                    if (thread.IsAlive)
                    {
                        thread.Abort();
                    }
                }

                checkMapsForCorrectDifficulty();

                this.currentTutorialCounter = 4;
                this.currentLevelMapCounter = 0;
                this.regenerateMaps();
            }
            
        }

        /*public Boolean SkipTutorial
        {
            get { return this.doTutorial; }
            set 
            { 
                this.doTutorial = value;
                if (value == false)
                {
                    this.RestartTutorial();
                }
            }
        }*/

        public void ResetSurvival()
        {
            this.currDifficulty = Difficulty.Noob;
            this.doTutorial = false;
            this.Reset();
        }

        public void RestartSurvival(Difficulty difficulty)
        {
            this.currDifficulty = difficulty;
            this.doTutorial = false;
            this.Reset();
        }

        public void RestartTutorial()
        {
            this.currDifficulty = Difficulty.Tutorial;
            this.doTutorial = true;
            this.Reset();
        }

        private void checkMapsForCorrectDifficulty()
        {
            Difficulty tempDifficulty = this.currDifficulty;
            if (tempDifficulty == Difficulty.Tutorial)
            {
                tempDifficulty++;
            }


            IEnumerator Enum = mapList.GetEnumerator();
            Boolean hasNext = Enum.MoveNext();

            while (hasNext)
            {
                if (((Map)Enum.Current).mapDifficulty != this.currDifficulty)
                {
                    mapList.Remove((Map)Enum.Current);
                    Enum = mapList.GetEnumerator();
                }

                hasNext = Enum.MoveNext();
            }

            numberOfGeneratedMaps = mapList.Count;
        }

        public int Count()
        {
            if (this.doTutorial)
            {
                return currentTutorialCounter;
            }
            else
            {
                return currentLevelMapCounter;
            }
        }

        /*public Boolean needToResetMaps()
        {
            if (currentLevelMapCounter == 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }*/
    }
}
